<!--
* @author wn
* @date 2022/07/08 11:28:46
* @description: 账号登录组件  配合 component组件 is 抽离
!-->
<template>
	<div class="login-form">
		<!-- 登录方式 导航 -->
		<nav>
			<a href="javascript:;" v-if="isMsgLogin" @click="isMsgLogin = false">
				<i class="iconfont icon-user"> 使用账号登录 </i>
			</a>
			<a href="javascript:;" v-else @click="isMsgLogin = true">
				<i class="iconfont icon-msg"> 使用短信登录 </i>
			</a>
		</nav>
		<!-- 表单主体 登录 - 用户名和密码-->
		<!-- 1 请输入用户名或密码 -->
		<Form
			class="form"
			:validation-schema="mySchema"
			v-slot="{ errors }"
			ref="target"
		>
			<template v-if="!isMsgLogin">
				<div class="form-item">
					<!-- 包含成功 失败 -->
					<div class="input">
						<i class="iconfont icon-user"></i>
						<Field
							name="account"
							v-model="form.account"
							type="text"
							placeholder="请输入用户名"
							:class="{ errors: errors.account }"
						/>
					</div>
					<div class="error">
						<i class="iconfont icon-warning" v-if="errors.account" />
						{{ errors.account }}
					</div>
				</div>
				<div class="form-item">
					<div class="input">
						<i class="iconfont icon-lock"></i>
						<Field
							name="password"
							v-model="form.password"
							type="password"
							placeholder="请输入密码"
							:class="{ errors: errors.password }"
						/>
					</div>
					<div class="error">
						<i class="iconfont icon-warning" v-if="errors.password" />
						{{ errors.password }}
					</div>
				</div>
			</template>
			<!-- 2 手机验证码 -->
			<template v-else>
				<div class="form-item">
					<div class="input">
						<i class="iconfont icon-user"></i>
						<Field
							name="mobile"
							v-model="form.mobile"
							type="text"
							placeholder="请输入手机号"
							:class="{ errors: errors.mobile }"
						/>
					</div>
					<div class="error">
						<i class="iconfont icon-warning" v-if="errors.mobile" />
						{{ errors.mobile }}
					</div>
				</div>
				<div class="form-item">
					<div class="input">
						<i class="iconfont icon-code"></i>
						<Field
							name="code"
							v-model="form.code"
							type="number"
							placeholder="请输入验证码"
							:class="{ errors: errors.code }"
						/>
						<span class="code" @click="btnSend">
							{{ time === 0 ? '发送验证码' : `${time}秒后发送` }}
						</span>
					</div>
					<div class="error">
						<i class="iconfont icon-warning" v-if="errors.code" />
						{{ errors.code }}
					</div>
				</div>
			</template>
			<!-- 同意 -->
			<div class="form-item">
				<div class="agree">
					<Field as="xtx-check-box" name="isAgree" v-model="form.isAgree" />
					<span>我已同意</span>
					<a href="javascript:;">《隐私条款》</a>
					<span>和</span>
					<a href="javascript:;">《服务条款》</a>
				</div>
				<div class="error">
					<i class="iconfont icon-warning" v-if="errors.isAgree" />
					{{ errors.isAgree }}
				</div>
			</div>
			<!-- 登陆按钮 -->
			<a href="javascript:;" class="btn" @click="login">登录</a>
		</Form>
		<!-- QQ登陆 -->
		<div class="action">
			<a
				href="https://graph.qq.com/oauth2.0/authorize?client_id=100556005&response_type=token&scope=all&redirect_uri=http%3A%2F%2Fwww.corho.com%3A8080%2F%23%2Flogin%2Fcallback"
			>
				<img
					src="https://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_7.png"
					alt=""
				/>
			</a>
			<!-- <span id="qqLoginBtn"></span> -->
			<div class="url">
				<a href="javascript:;">忘记密码</a>
				<router-link to="/register">免费注册</router-link>
			</div>
		</div>
	</div>
</template>
<script>
import { reactive, computed, ref } from 'vue'
import { Form, Field } from 'vee-validate'
import schema from '@/utils/vee-validate-schema'
import Message from '@/components/library/message'
import {
	userAccountLogin,
	userMobileLogin,
	userMobileLoginMsg,
} from '@/network/user'
import { useStore } from 'vuex'
import { useRoute, useRouter } from 'vue-router'
import { useCountDownBtn } from '@/hooks'
// import { useIntervalFn } from '@vueuse/core'
// vue 组件中需要 导入 QC 才可以使用  webpack 打包需要忽略
// import QC from 'qc'

export default {
	name: 'LoginForm',
	components: { Form, Field },
	setup() {
		// 获取 Form 实例
		const target = ref(null)
		// 是否短信登录
		// 计算属性 变化时 重置 form数据 以及 error数据
		const isLogion = ref(false)
		const isMsgLogin = computed({
			set(v) {
				isLogion.value = v
				// 重置表单信息
				form.isAgree = true
				form.account = null
				form.password = null
				form.mobile = null
				form.code = null
				// 清空错误信息
				target.value.resetForm()
			},
			get() {
				return isLogion.value
			},
		})
		// 表单信息对象 - 后续提交表单时需要校验当前对象
		const form = reactive({
			isAgree: true,
			account: null,
			password: null,
			mobile: null,
			code: null,
		})
		const mySchema = {
			account: schema.account,
			password: schema.password,
			mobile: schema.mobile,
			code: schema.code,
		}
		const store = useStore()
		const router = useRouter()
		const route = useRoute()
		// 登陆按钮 需要对 表单进行整体校验  validate   返回 promise
		const login = async () => {
			// .validate() 获取表单校验结果：true 表示校验通过，false 不通过
			const valid = await target.value.validate()
			// 验证通过  发送登陆请求
			if (valid) {
				try {
					let UserResult
					// 1 账号密码登陆
					if (!isMsgLogin.value) {
						const accountData = {
							account: form.account,
							password: form.password,
						}
						const { result } = await userAccountLogin(accountData)
						UserResult = result
					} else {
						// 2 手机 验证码登陆
						const mobileData = {
							mobile: form.mobile,
							code: form.code,
						}
						const { result } = await userMobileLogin(mobileData)
						UserResult = result
					}
					// 1.vuex  把 token 和 用户信息 存储起来
					const userInfo = {
						id: UserResult.id,
						avatar: UserResult.avatar,
						nickName: UserResult.nickName,
						account: UserResult.account,
						mobile: UserResult.mobile,
						token: UserResult.token,
					}
					store.commit('user/setUser', userInfo)
					// 登陆成功 合并本地购物车
					await store.dispatch('cart/mergeCart')
					// 2. 跳转页面（回调到登录前401引发的 或者 跳首页）
					router.push(route.query.redirectUrl || '/')
					// 3. 登录成功提示
					Message({ type: 'success', message: '登录成功' })
				} catch (error) {
					// console.dir(error)
					Message({
						type: 'error',
						message: `${
							error.response ? error.response.data.message : '登陆失败'
						}`,
					})
				}
			} else {
				// 表单验证失败
				Message({ type: 'warn', message: '表单校验失败' })
			}
		}
		// 60秒倒计时 vueUse
		const { time, resume } = useCountDownBtn()
		// const time = ref(0)
		// // 1 回调函数 2 时间间隔 3 是否立刻执行
		// const { resume, pause } = useIntervalFn(
		// 	() => {
		// 		time.value--
		// 		time.value <= 0 && pause()
		// 	},
		// 	1 * 1000,
		// 	{
		// 		immediate: false,
		// 	}
		// )

		// 组件销毁时  也要停止定时器
		// onUnmounted(() => pause())

		// 发送手机验证码
		const btnSend = async () => {
			// 1 校验 手机号正确  true  失败-->String String也是true ===
			const mobileResult = schema.mobile(form.mobile)
			// 2 且倒计时 必须是0 其他时间已经触发过了 在等待中
			if (mobileResult === true && time.value === 0) {
				try {
					// 3 调用获取验证码接口
					await userMobileLoginMsg(form.mobile)
					// 4 无需结果  能继续执行 就是成功
					// 5 开启定时器 与 消息提示 与 60秒
					time.value = 60
					resume()
					Message({ type: 'success', message: '发送成功' })
				} catch (error) {
					Message({
						type: 'warn',
						message: `${
							error.response ? error.response.data.message : '发送失败'
						}`,
					})
				}
			} else {
				// 5 校验失败  errors 提示  time不是 0 校验成功不提示
				// Form组件 setFieldError(哪个name,错误信息)触发 v-slot="{ errors }.mobile
				mobileResult === true ||
					target.value.setFieldError('mobile', mobileResult)
			}
		}
		// js 生成QQ按钮做法
		// onMounted(() =>
		// 	QC.Login({
		// 		btnId: 'qqLoginBtn', // 插入按钮的节点id
		// 	})
		// )
		return {
			isMsgLogin,
			form,
			mySchema,
			target,
			time,
			login,
			btnSend,
		}
	},
}
</script>
<style scoped lang="less">
.login-form {
	nav {
		padding: 15px 40px;
		text-align: right;
		a {
			color: @xtxColor;
			i {
				font-size: 14px;
			}
		}
	}
	.form {
		padding: 0 40px;
		&-item {
			position: relative;
			margin-bottom: 28px;
			.input {
				position: relative;
				height: 36px;
				> i {
					position: absolute;
					left: 1px;
					top: 1px;
					width: 34px;
					height: 34px;
					background: #cfcdcd;
					color: #fff;
					text-align: center;
					line-height: 34px;
					font-size: 18px;
				}
				// 输入框
				input {
					padding-left: 44px;
					border: 1px solid #cfcdcd;
					height: 36px;
					line-height: 36px;
					width: 100%;
					&.errors {
						border-color: @priceColor;
					}
					&.active,
					&:focus {
						border-color: @xtxColor;
					}
				}
				// 短信验证码按钮
				.code {
					position: absolute;
					right: 1px;
					top: 1px;
					text-align: center;
					line-height: 34px;
					font-size: 14px;
					background: #f5f5f5;
					color: #666;
					width: 90px;
					height: 34px;
					cursor: pointer;
				}
			}
			.error {
				position: absolute;
				font-size: 12px;
				line-height: 28px;
				color: @priceColor;
				i {
					font-size: 14px;
					margin-right: 2px;
				}
			}
			.agree {
				a {
					color: #069;
				}
			}
		}
		// 登陆
		.btn {
			display: block;
			width: 100%;
			height: 40px;
			color: #fff;
			text-align: center;
			line-height: 40px;
			background: @xtxColor;
			&.disabled {
				background: #cfcdcd;
			}
		}
	}
	// QQ登陆
	.action {
		display: flex;
		justify-content: space-between;
		align-items: center;
		padding: 20px 40px;
		.url {
			a {
				color: #999;
				margin-left: 10px;
			}
		}
	}
}
</style>
